import 'package:dio/dio.dart';
import 'package:flutter_douban/network/http_code.dart';
import 'package:flutter_douban/network/http_data.dart';
import 'package:flutter_douban/network/http_interceptor.dart';


enum RequestMethod {
  GET,
  POST,
  PUT,
  DELETE,
}

class HttpManager {
  static const CONTENT_TYPE_JSON = "application/json";
  static const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";

  static const requestMethods = ["GET", "POST", "PUT", "DELETE"];

  Dio _dio = Dio()
    ..options.baseUrl = "https://api.douban.com"
    ..options.connectTimeout = 30000
    ..options.receiveTimeout = 30000;

  HttpManager() {
    // 添加请求拦截器
    _dio.interceptors.add(TokenInterceptors());
    _dio.interceptors.add(LogInterceptors());
    _dio.interceptors.add(ErrorInterceptors(_dio));
    _dio.interceptors.add(ResponseInterceptors());
  }

  /// 数据请求统一入口
  /// [method] 请求方法
  /// [path] 请求路径
  /// [data] body 参数  post  默认json编码
  /// [queryParameters]  追加url参数 如‘path？api=123&...’
  /// [header]  自定义请求头
  /// [onSendProgress] 注意：如果要监听提交进度，则必须设置content-length，反之则是可选的。
  Future<HttpData> request(
    RequestMethod method,
    String path, {
    data,
    Map<String, dynamic> queryParameters,
    Map<String, dynamic> header,
    Options option,
    CancelToken cancelToken,
    ProgressCallback onSendProgress,
    ProgressCallback onReceiveProgress,
  }) async {
    Map<String, dynamic> headers = Map<String, dynamic>();
    if (header != null) {
      headers.addAll(header);
    }

    if (option != null) {
      option.headers = headers;
    } else {
      option = Options(method: "GET");
      option.headers = headers;
    }

    option.method = requestMethods[method.index];

    resultError(DioError e) {
      Response errorResp;
      if (e.response != null) {
        errorResp = e.response;
      } else {
        errorResp = Response(statusCode: 888);
      }

      if (e.type == DioErrorType.CONNECT_TIMEOUT ||
          e.type == DioErrorType.RECEIVE_TIMEOUT) {
        errorResp.statusCode = HttpCode.NETWORK_TIMEOUT;
      }

      return HttpData(HttpCode.errorHandle(errorResp.statusCode, e.message),
          false, errorResp.statusCode);
    }

    Response response;
    try {
      response = await _dio.request(path,
          data: data,
          queryParameters: queryParameters,
          options: option,
          cancelToken: cancelToken,
          onSendProgress: onSendProgress,
          onReceiveProgress: onReceiveProgress);
    } on DioError catch (error) {
      return resultError(error);
    }
    if (response.data is DioError) {
      return resultError(response.data);
    }
    return response.data;
  }
}

final HttpManager httpManager = HttpManager();
